﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RSProject
{
    public partial class dataView : Form
    {
        int band1, band2, band3;
        int lines, samples;
        byte[,,] dataArray;
        Point mouseDownPoint = new Point();
        bool isMove = false;
        int zoomStep = 100;
        Bitmap bmp;

        private void pbView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Cursor.Current = Cursors.Hand;
                mouseDownPoint.X = Cursor.Position.X;   //记录鼠标左键按下时位置
                mouseDownPoint.Y = Cursor.Position.Y;
                isMove = true;
                pbView.Focus();    //鼠标滚轮事件(缩放时)需要picturebox有焦点
            }
        }

        private void pnlView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Cursor.Current = Cursors.Hand;
                mouseDownPoint.X = Cursor.Position.X;   //记录鼠标左键按下时位置
                mouseDownPoint.Y = Cursor.Position.Y;
                isMove = true;
            }
        }

        private void dataView_MouseDown(object sender, MouseEventArgs e)
        {
            if (pnlView.Visible == true)
            {
                pbView.Focus();
            }
        }

        private void pbView_MouseUp(object sender, MouseEventArgs e)
        {

            if (e.Button == MouseButtons.Left)
            {
                Cursor.Current = Cursors.Default;
                isMove = false;
            }
        }

        private void pbView_MouseMove(object sender, MouseEventArgs e)
        {
            pbView.Focus();    //鼠标在picturebox上时才有焦点，此时可以缩放
            if (isMove)
            {
                int x, y;           //新的pbView.Location(x,y)
                int moveX, moveY;   //X方向，Y方向移动大小。
                moveX = Cursor.Position.X - mouseDownPoint.X;
                moveY = Cursor.Position.Y - mouseDownPoint.Y;
                x = pbView.Location.X + moveX;
                y = pbView.Location.Y + moveY;
                pbView.Location = new Point(x, y);
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
            }
        }

        private void pnlView_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Cursor.Current = Cursors.Default;
                isMove = false;
            }
        }

        private void pnlView_MouseMove(object sender, MouseEventArgs e)
        {
            pnlView.Focus();  //鼠标不在picturebox上时焦点给别的控件，此时无法缩放            
            if (isMove)
            {
                int x, y;           //新的pbView.Location(x,y)
                int moveX, moveY;   //X方向，Y方向移动大小。
                moveX = Cursor.Position.X - mouseDownPoint.X;
                moveY = Cursor.Position.Y - mouseDownPoint.Y;
                x = pbView.Location.X + moveX;
                y = pbView.Location.Y + moveY;
                pbView.Location = new Point(x, y);
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
            }
        }

        private void pbView_MouseWheel(object sender, MouseEventArgs e)
        {
            int x = e.Location.X;
            int y = e.Location.Y;
            int ow = pbView.Width;
            int oh = pbView.Height;
            int VX, VY;     //因缩放产生的位移矢量
            if (e.Delta > 0)    //放大
            {
                //第①步
                pbView.Width += zoomStep;
                pbView.Height += zoomStep;
                //第②步
                PropertyInfo pInfo = pbView.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
                    BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(pbView, null);
                //第③步
                pbView.Width = rect.Width;
                pbView.Height = rect.Height;
            }
            if (e.Delta < 0)    //缩小
            {
                //防止一直缩成负值
                if (pbView.Width <= bmp.Width)
                    return;

                pbView.Width -= zoomStep;
                pbView.Height -= zoomStep;
                PropertyInfo pInfo = pbView.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
                    BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(pbView, null);
                pbView.Width = rect.Width;
                pbView.Height = rect.Height;
            }
            //第④步，求因缩放产生的位移，进行补偿，实现锚点缩放的效果
            VX = (int)((double)x * (ow - pbView.Width) / ow);
            VY = (int)((double)y * (oh - pbView.Height) / oh);
            pbView.Location = new Point(pbView.Location.X + VX, pbView.Location.Y + VY);
        }

        private void dataView_Shown(object sender, EventArgs e)
        {
            if (band1 > 0)
            {
                // 显示直方图
                if (band2 == -1)
                {
                    Text = "直方图";
                    Size = new Size(1000,600);

                    //生成直方图
                    Refresh();
                    Graphics g = CreateGraphics();
                    int width = Width;
                    int height = Height;
                    g.TranslateTransform(100, 480);
                    Pen pen1 = new Pen(Color.Blue, 1);
                    Pen pen2 = new Pen(Color.Black, 1);
                    g.ScaleTransform(1, -1);

                    int[] a = new int[256];

                    for (int j = 0; j < Global.head.lines; j++)
                    {
                        for (int k = 0; k < Global.head.samples; k++)
                        {
                            int n = band1 - 1;
                            for (int p = 0; p < 256; p++)
                            {
                                if (Global.intArray[n, j, k] == p)
                                {
                                    a[p]++;
                                    break;
                                }
                            }
                        }
                    }


                    for (int m = 0; m < 256; m++)
                    {

                        Point p1 = new Point(m * 3, 0);
                        Point p2 = new Point(m * 3, a[m] / 100);
                        g.DrawLine(pen1, p1, p2);
                    }
                    g.DrawLine(pen2, 0, 400, 0, 0);
                    g.DrawLine(pen2, 0, 0, 800, 0);

                    g.ScaleTransform(1, -1);
                    g.DrawString("0", new Font("New Timer", 15), Brushes.Black, new PointF(0, 20));
                    g.DrawString("50", new Font("New Timer", 15), Brushes.Black, new PointF(150, 20));
                    g.DrawString("100", new Font("New Timer", 15), Brushes.Black, new PointF(300, 20));
                    g.DrawString("150", new Font("New Timer", 15), Brushes.Black, new PointF(450, 20));
                    g.DrawString("200", new Font("New Timer", 15), Brushes.Black, new PointF(600, 20));
                    g.DrawString("250", new Font("New Timer", 15), Brushes.Black, new PointF(750, 20));
                    g.DrawString("灰度", new Font("New Timer", 15), Brushes.Black, new PointF(820, -10));

                    g.DrawString(" 5000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -50));
                    g.DrawString("10000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -100));
                    g.DrawString("15000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -150));
                    g.DrawString("20000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -200));
                    g.DrawString("25000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -250));
                    g.DrawString("30000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -300));
                    g.DrawString("35000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -350));
                    g.DrawString(" 像元数", new Font("New Timer", 15), Brushes.Black, new PointF(-40, -450));

                    pen1.Dispose();
                    pen2.Dispose();
                }

                // 显示累计直方图
                if (band2 == -2)
                {
                    Text = "累计直方图";
                    Size = new Size(1000, 600);

                    //生成累计直方图
                    Refresh();
                    Graphics g = this.CreateGraphics();
                    int width = this.Width;
                    int height = this.Height;
                    g.TranslateTransform(100, 480);
                    Pen pen1 = new Pen(Color.Red, 1);
                    Pen pen2 = new Pen(Color.Black, 1);
                    g.ScaleTransform(1, -1);
                    int sum = 0;
                    int[] a = new int[256];

                    for (int j = 0; j < Global.head.lines; j++)
                    {
                        for (int k = 0; k < Global.head.samples; k++)
                        {
                            int n = band1 - 1;
                            for (int p = 0; p < 256; p++)
                            {
                                if (Global.intArray[n, j, k] == p)
                                {
                                    a[p]++;
                                    break;
                                }
                            }
                        }
                    }

                    for (int m = 0; m < 256; m++)
                    {

                        sum += a[m];
                        Point p1 = new Point(m * 3, 0);
                        Point p2 = new Point(m * 3, sum / 1000);
                        g.DrawLine(pen1, p1, p2);

                    }
                    g.DrawLine(pen2, 0, 400, 0, 0);
                    g.DrawLine(pen2, 0, 0, 800, 0);

                    g.ScaleTransform(1, -1);
                    g.DrawString("0", new Font("New Timer", 15), Brushes.Black, new PointF(0, 20));
                    g.DrawString("50", new Font("New Timer", 15), Brushes.Black, new PointF(150, 20));
                    g.DrawString("100", new Font("New Timer", 15), Brushes.Black, new PointF(300, 20));
                    g.DrawString("150", new Font("New Timer", 15), Brushes.Black, new PointF(450, 20));
                    g.DrawString("200", new Font("New Timer", 15), Brushes.Black, new PointF(600, 20));
                    g.DrawString("250", new Font("New Timer", 15), Brushes.Black, new PointF(750, 20));
                    g.DrawString("灰度", new Font("New Timer", 15), Brushes.Black, new PointF(820, -10));

                    g.DrawString(" 50000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -50));
                    g.DrawString("100000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -100));
                    g.DrawString("150000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -150));
                    g.DrawString("200000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -200));
                    g.DrawString("250000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -250));
                    g.DrawString("300000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -300));
                    g.DrawString("350000", new Font("New Timer", 15), Brushes.Black, new PointF(-80, -350));
                    g.DrawString("像元数", new Font("New Timer", 15), Brushes.Black, new PointF(-40, -450));

                    pen1.Dispose();
                    pen2.Dispose();
                }

                // 显示图像
                if (band2 > 0 && band3 > 0)
                {
                    Text = "图像显示";
                    Size = new Size(lines + 200, samples + 100);

                    pnlView.Visible = true;
                    pbView.Size = new Size(lines, samples);

                    bmp = new Bitmap(samples, lines);
                    Graphics gp = Graphics.FromImage(bmp);
                    gp.Clear(Color.White);
                    for (int y = 0; y < lines; y++)
                    {
                        for (int x = 0; x < samples; x++)
                        {
                            byte r = dataArray[band1 - 1, y, x];
                            byte g = dataArray[band2 - 1, y, x];
                            byte b = dataArray[band3 - 1, y, x];
                            Color color = Color.FromArgb(r, g, b);

                            gp.FillRectangle(new SolidBrush(color), x, y, 20, 20);
                        }
                    }
                    gp.Save();

                    pbView.Image = bmp;
                    pbView.Left = (pnlView.Width - pbView.Width) / 2;
                    pbView.Top = (pnlView.Height - pbView.Height) / 2;
                }
            }
        }

        public dataView(int band1, int band2)
        {
            InitializeComponent();
            this.band1 = band1;
            this.band2 = band2;
            lines = Global.head.lines;
            samples = Global.head.samples;
        }

        public dataView(int band1, int band2, int band3, byte[,,] dataArray)
        {
            InitializeComponent();
            this.band1 = band1;
            this.band2 = band2;
            this.band3 = band3;
            this.dataArray = dataArray;
            this.lines = Global.head.lines;
            this.samples = Global.head.samples;
        }
    }
}
